import datetime
import json
import os
import random
import re
import string
import time
from urllib.parse import unquote, urlencode

import jsonpath
import requests
from faker import Faker
from lxml import etree

from api.client import HttpClient
from common.logger import Logger
from common.read_yaml import ReadYaml_By_Root_Dict
from common.utils import Utils

fake = Faker(locale='zh_CN')
utils = Utils()
requests.packages.urllib3.disable_warnings()
env = ReadYaml_By_Root_Dict("configs/environment_var.yml").get_yaml_data()  # 读取数据
business_params = ReadYaml_By_Root_Dict("case_online/business_payload.yml").get_yaml_data()  # 读取数据
lessor_key = "id-"+''.join(random.sample(string.ascii_lowercase + string.digits, 22))

def jp(obj, expr, result_type='VALUE', debug=0, use_eval=True):
    Logger.info(f'jsonpath表达式：{expr}')
    return jsonpath.jsonpath(obj, expr, result_type='VALUE', debug=0, use_eval=True)


class MySpace_Asset(HttpClient):
    def __init__(self, session=None):
        self.session = session
        super().__init__(self.session)
        # 获取环境参数，然后得到环境参数的对应的值
        environ = self.env_flag
        # environ = "saas_myspace_test"
        self.__tenant = jp(env,f'$.{environ}.app_tenant_id')[0]
        self.__app_code = jp(env,f'$.{environ}.app_code')[0]
        self.__passport = jp(env,f'$.{environ}.business_host.passport')[0]
        self.__bms = jp(env,f'$.{environ}.business_host.bms')[0]
        self.__kfapi = jp(env,f'$.{environ}.business_host.kfapi')[0]
        self.__kefu = jp(env,f'$.{environ}.business_host.kefu')[0]
        self.users = jp(env,f'$.{environ}.users')[0] # 用户信息，字典：{user:password}
        self.__org_id = "11b11db4-e907-4f1f-8835-b9daab6e1f23"

        self.__headers = {'sec-ch-ua': '"Microsoft Edge";v="107", "Chromium";v="107", "Not=A?Brand";v="24"',
                   'sec-ch-ua-mobile': '?0',
                   'sec-ch-ua-platform': '"Windows"',
                   'Upgrade-Insecure-Requests': '1',
                   'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.42',
                   'Accept': 'application/json, text/plain, */*',
                   'Content-Type': 'application/json',
                   'Sec-Fetch-Site': 'same-site'}

    # 登录
    def login_myspace(self, userName, password):
        self.request = self.session
        URL = f'https://passport.test.myspacex.cn/auth/login?o=jq'
        r = self.request.get(URL, headers=self.__headers, verify=False)
        csrf = self.get_html_attr_val(r.text,'#loginForm [name="_csrf"]','value')
        data = {"_csrf":csrf,
                "tenantCode":"jq",
                "userName":userName,
                "password":password,
                "code":""}
        data_encode=urlencode(data) # 得到带&格式的参数
        print(f"csrf:{data_encode}")
        headers = self.__headers.copy()
        headers.update({"Content-Type":"application/x-www-form-urlencoded"})
        r = self.request.post(URL, headers=headers, data=data_encode, verify=False)

    def switch_Asset(self):
        """
        切换到资管系统
        Returns:

        """
        URL="https://asset.test.myspacex.cn/?_smp=AssetCenter"
        r = self.request.get(URL, headers=self.__headers, verify=False)
        print(r.status_code)

    def get_asset(self,index=0)->dict:
        """
        获取资产列表，默认获取第一个

        Returns: 第一个资产，返回{"id":id,"name":name}

        """
        URL=f"https://asset.test.myspacex.cn/asset-property/asset/get-asset-list-by-scene?o=jq&org_id={self.__org_id}"
        payload = {"page":1,"page_size":20,"scene":"资产盘点","org_id":self.__org_id,"is_valid":True}
        resp = self.request.post(URL,headers=self.__headers,json=payload,verify=False)
        if resp.status_code != 200:
            assert False, f"请求失败"
        elif resp.json()['message'] != "ok":
            assert False, f"查询失败，{resp.json()['message']}"
        else:
            id = jp(resp.json(),f'$.data.items[{index}].id')[0]
            name = jp(resp.json(),f'$.data.items[{index}].name')[0]
            return {"id":id,"name":name}

    def get_receive_type_id(self,index=0) :
        """
        获取资产接收类型id，默认获取第一个接收类型
        Args:
            org_id: 11b11db4-e907-4f1f-8835-b9daab6e1f23

        Returns: 获取资产接收类型id

        """
        URL = f"https://asset.test.myspacex.cn/parameter/common-config/list?t={self.t_ms()}&_smp=AssetCenter&org_id={self.__org_id}&o=jq&code=receiveType&enabled=1"
        resp = self.request.get(URL,headers=self.__headers,verify=False)
        if resp.status_code != 200:
            assert False, f"请求失败"
        elif resp.json()['msg'] != "":
            assert False, f"查询失败，{resp.json()['msg']}"
        else:
            receive_type_id = jp(resp.json(),f'$.data.items[{index}].id')[0]
            return receive_type_id

    def add_asset_receive(self, receive_type_id, asset_id, object_name):
        URL = f"https://asset.test.myspacex.cn/resource/adjust-record/publish-in-out?t={self.t_ms()}&o=jq&_smp=AssetCenter&org_id={self.__org_id}"
        cur_time = time.strftime('%Y-%m-%d %H:%M:%S')
        cur_date = time.strftime('%Y-%m-%d')
        name=f"资产接收{cur_time}"
        payload = {"type": "接收", "remark": "", "reason": name, "attachment": [], "effect_date": cur_date,
                   "business_data": {"receive_type_id": receive_type_id}, "items": [
                {"object_id": asset_id, "object_name": object_name,
                 "business_data": {"id": asset_id}}]}
        resp = self.request.post(URL, headers=self.__headers, json=payload, verify=False)
        if resp.status_code != 200:
            assert False, f"请求失败"
        elif resp.json()['msg'] != "":
            assert False, f"查询失败，{resp.json()['msg']}"
        else:
            Logger.info(f'资产接收响应：{resp.json()}')
            id = resp.json()['data']['id']
            return id

    def get_enable_asset_inventory_id(self):
        url = f"https://asset.test.myspacex.cn/parameter/common-config/approval?t={self.t_ms()}&o=jq&_smp=AssetCenter&org_id={self.__org_id}"
        resp = self.request.get(url,headers=self.__headers, verify=False)
        if resp.status_code != 200:
            assert False, f"请求失败"
        elif resp.json()['msg'] != "":
            assert False, f"查询失败，{resp.json()['msg']}"
        else:
            id = jp(resp.json(),'$..[?(@.name=="资产接收")].id')[0]
            return id

    # 启用工作流审批
    def enable_bpm_approve(self):
        url = f"https://asset.test.myspacex.cn/parameter/common-config/edit?t={self.t_ms()}&o=jq&_smp=AssetCenter&org_id={self.__org_id}"
        headers = {
            "Accept": "application/json, text/plain, */*",
            "X-YL-Tenant-Code": self.__tenant,
            # "Authorization": "Bearer eyJ0eXBlIjoiSldUIiwiYWxnbyI6InNoYTI1NiIsImNyZWF0ZWRBdCI6MTY2NTgyNDc4NiwiZXhwaXJlVGltZSI6MzAwLCJyZWZyZXNoRXhwaXJlVGltZSI6NzIwMH0.eyJhY2NvdW50IjoicmV0ZXN0aW5nIiwiY29tcGFueUlEIjoiMTFiMTFkYjQtZTkwNy00ZjFmLTg4MzUtYjlkYWFiNmUxZjIzIiwibG9naW5VdWlkIjoiMjAyMjEwMTUxNDAzMTE2MzRhNGQxZmU2OTQ4IiwibW9iaWxlIjoiMTY2NjY2NjY2NjYiLCJvcGVuSWQiOiJjN2ZkZWVjY2JlMGI2YWQyNzM4NmQxMjMwYzg0NTUwODM3NWQiLCJvcmdJRCI6IjExYjExZGI0LWU5MDctNGYxZi04ODM1LWI5ZGFhYjZlMWYyMyIsIm9yZ05hbWUiOiJcdTY2N2FcdTYxNjdcdTcyNjlcdTRlMWFcdTk2YzZcdTU2ZTIiLCJvcmdOYW1lUGF0aCI6Ilx1NjY3YVx1NjE2N1x1NzI2OVx1NGUxYVx1OTZjNlx1NTZlMiIsInBvc3ROYW1lIjoiXHU2ZDRiXHU4YmQ1XHU2NTcwXHU2MzZlXHU1Yzk3XHU0ZjRkXHU1NDBkXHU3OWYwXHU2ZDRiXHU4YmQ1XHU2NTcwXHU2MzZlXHU2NzAwXHU1OTI3XHU5NTdmXHU1ZWE2XHU2ZDRiXHU4YmQ1XHU2NzAwXHU1OTI3XHU5NTdmXHU1ZWE2XHU2ZDRiXHU4YmQ1XHU2NzAwXHU1OTI3XHU5NTdmXHU1ZWE2XHU2ZDRiXHU4YmQ1XHU2NzAwXHU1OTI3XHU5NTdmXHU1ZWE2XHU2ZDRiXHU4YmQ1XHU2NzAwXHU1OTI3XHU5NTdmXHU1ZWE2XHU2ZDRiXHU4YmQ1XHU2NzAwXHU1OTI3XHU5NTdmXHU1ZWE2XHU2ZDRiXHU4YmQ1XHU2NzAwMSIsInRlbmFudENvZGUiOiJyZXRlc3RpbmciLCJ0ZW5hbnRJRCI6IjExYjExZGI0LWU5MDctNGYxZi04ODM1LWI5ZGFhYjZlMWYyMyIsInRlbmFudE5hbWUiOiJcdTY2N2FcdTYxNjdcdTcyNjlcdTRlMWFcdTk2YzZcdTU2ZTIiLCJ1bmlvbklkIjoiODUwZGNhM2YzM2M5YmFmY2Y2MTRhNzUyYzJlZmI0OWNlNjhhIiwidXNlcklEIjoiMjJiMTFkYjQtZTkwNy00ZjFmLTg4MzUtYjlkYWFiNmUxZjIzIiwidXNlcklkIjoiMjJiMTFkYjQtZTkwNy00ZjFmLTg4MzUtYjlkYWFiNmUxZjIzIiwidXNlclR5cGUiOiJTVVBFUl9BRE1JTiIsInVzZXJuYW1lIjoiXHU4ZDg1XHU3ZWE3XHU3NTI4XHU2MjM3In0.AV16e-mMbHFKlDeKtKKljnAO9EQzIPJjtnv7cr0hqOI",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36"
        }
        id = self.get_enable_asset_inventory_id()
        payload = {"id":id,"code":"ApprovalStockTakeOpen","name":"资产接收","is_enabled":"1"}
        resp = self.request.post(url=url, headers=headers, json=payload, verify=False)
        print(f'enable_bpm_approve:{resp.json()}')
        if resp.status_code != 200:
            assert False, f"请求失败"
        elif resp.json()['msg'] != "":
            assert False, f"查询失败，{resp.json()['msg']}"
        else:
            Logger.info(f"流程审批设置成功！")


    def commit_approval_common(self,business_id):
        """
        获取跳转url
        Args:
            business_id:

        Returns:

        """
        URL=f"https://asset.test.myspacex.cn/asset-base/workflow/commit-approval-common?t={self.t_ms()}&_smp=AssetCenter&org_id={self.__org_id}&o=jq&business_id={business_id}&scene=接收资产调整单"
        resp = self.request.get(URL, headers=self.__headers, verify=False)
        if resp.status_code != 200:
            assert False, f"请求失败，响应码：{resp.status_code}"
        elif resp.json()['message'] != "ok":
            assert False, f"查询失败，{resp.json()['message']}"
        else:
            print(f"commit_approval_common:{resp.json()}")
            transfer_url = jp(resp.json(), '$.data')[0]
            print(f"transfer_url:{transfer_url}")
            Logger.info(f"获取跳转地址：{transfer_url}")
            return transfer_url

    def t_ms(self):
        """
        获取毫秒时间戳
        Returns:

        """
        t_original = time.time()
        t_ms = int(round(t_original * 1000))
        return t_ms

    # 流程中转页面
    def get_transfer_by_choice_module(self, transfer_url, module_name=""):
        """
        流程中转页面请求，通过模板名称获取跳转流程发起或流程审批页面地址
        Args:
            transfer_url: 流程中转url

        Returns:流程发起或者流程审批的url：/flowinstance/approval/index或/flowinstance/process/create

        """
        url = transfer_url
        r = self.request.get(url, verify=False, allow_redirects=False)
        # 判断跳转请求是否返回302，如果返回302，说明只有一个流程模板，可以通过请求头的location获取带模板id的创建url
        if r.status_code == 302:
            create_or_approve_url = r.headers['Location']
        else:
            selector = etree.HTML(r.text)
            # 通过模板名称，获取流程模板id
            module_card_element = f'//*[text()="{module_name}"]/ancestor::div[@class="layui-card"]'
            try:
                # 模板不存在或者所需属性不存在，则进行断言
                click_module_card = selector.xpath(module_card_element)[0].attrib['onclick']
            except IndexError:
                Logger.error(f'出错啦！！模板path：【{module_card_element}】不存在！！')
                assert False, f'出错啦！！模板path：【{module_card_element}】不存在！！'
            except KeyError:
                Logger.error(f'出错啦！！模板path：【{module_card_element}】中的属性【onclick】不存在！！')
                assert False, f'出错啦！！模板path：【{module_card_element}】中的属性【onclick】不存在！！'
            process_template_id = re.findall(r".*createProccess\('(.*)'", click_module_card)[0]
            # 将流程模板id与跳转URL拼接，得到发起流程带模板ID的的跳转URL
            transfer_url_module = f"{transfer_url}&process_template_id={process_template_id}"
            print(f"transfer_url_module:{transfer_url_module}")
            # 在继续请求带模板id的跳转url，得到创建流程url
            create_or_approve_url = self.get_create_url(transfer_url_module)
        return create_or_approve_url

    def view_approval_common(self,task_id):
        URL=f'https://asset.test.myspacex.cn/asset-base/workflow/view-approval-common-v2?_smp=AssetCenter&org_id={self.__org_id}&o=jq&business_id={task_id}'
        resp = self.request.get(URL, headers=self.__headers, verify=False)
        if resp.status_code != 200:
            assert False, f"请求失败，响应码：{resp.status_code}"
        elif resp.json()['message'] != "ok":
            assert False, f"查询失败，{resp.json()['message']}"
        else:
            print(f"view_approval_common:{resp.json()}")
            transfer_url = jp(resp.json(), '$.data.approval_details_link')[0]
            print(f"transfer_url:{transfer_url}")
            Logger.info(f"获取审批跳转地址：{transfer_url}")
            return transfer_url

    # ------------------------------以上资管业务-----------------------
    def get_create_url(self, url):
        """
        获取创建流程url
        Returns:

        """
        r = self.request.get(url, verify=False, allow_redirects=False)
        create_or_approve_url = r.headers['Location']
        print(f'create_url:{create_or_approve_url}')
        return create_or_approve_url

#--------------------------------------待删除代码--------------------------
    def create_process(self, create_or_approve_url):
        """
        通过创建流程url，打开流程
        Args:
            create_or_approve_url:

        Returns:

        """
        url = create_or_approve_url
        resp = self.request.post(url, allow_redirects=False)
        if resp.status_code != 200:
            assert False, f"请求失败，响应码：{resp.status_code}"
        else:
            Logger.info(f"{url}请求成功")


    def initiation_process(self):
        url = f'https://workflow.test.myspacex.cn/{self.__tenant}/myykj/flowinstance/process/get-process-info?flow_template_id={self.flow_template_id}&package_id={self.package_id}&business_id={self.business_id}&started_organization_id=&o=retesting&_=1665889925861'
        resp = self.request.get(url, verify=False)
        if resp.status_code != 200:
            assert False, f"请求失败，响应码：{resp.status_code}"
        else:
            Logger.info(f"{url}请求成功")
            print(resp.json())

    def get_instance_id_by_task_id(self, task_id, status='审批中'):
        """
        通过task_id获取流程实例id，可以一个task可能有多次发起的流程
        Args:
            task_id: 任务ID
            status: 状态名称，中文：审批中、已作废等等。默认状态查询审批中的流程id

        Returns:对应任务id和状态的流程实例id

        """
        url = f'{self.__kefu}/{self.__tenant}/dailyservice/task-approve/list?task_id={task_id}&_smp=CustomerService.TaskRegist&pageSize=10&page=1&o={self.__tenant}&_=1666493730170'
        r = self.request.get(url, verify=False)
        print(f'get_instance_id_by_task_id:{r.json()}')
        instance_id = jp(r.json(), f"$..items[?(@.status=='{status}')].instance_id")[0]
        return instance_id

    def get_transfer_url(self, instance_id):
        url = f'{self.__kefu}/{self.__tenant}/dailyservice/task-approve/approve-detail-url?_smp=CustomerService.TaskRegist'
        payload = f'instance_id={instance_id}&o={self.__tenant}'
        header = {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
        r = self.request.post(url, data=payload, headers=header, verify=False)
        print(f'get_approve_url:{r.json()}')
        transfer_url = jp(r.json(), '$..approve_detail_url')[0]
        return transfer_url

    def business_initiate(self, user, passwd, module_name=""):
        myspace = self
        myspace.login_myspace(user, passwd)
        # myspace.login_myspace('jq', '1QAZ2wsx')
        myspace.switch_Asset()
        myspace.enable_bpm_approve()
        asset = myspace.get_asset()
        receive_type_id = myspace.get_receive_type_id()
        task_id = myspace.add_asset_receive(receive_type_id, asset['id'], asset['name'])
        # task_id = "3a080dc3-6055-41e1-cb58-4fbff95fa3a4"
        transfer_url = myspace.commit_approval_common(task_id)
        # 发起跳转返回给流程使用
        # create_url = myspace.get_transfer_by_choice_module(transfer_url, '资产接收-规划信息')
        create_url = myspace.get_transfer_by_choice_module(transfer_url, module_name)
        myspace_sess = myspace.session  # session返回给流程平台使用
        return myspace_sess, create_url, task_id

    def business_approve(self,user, passwd, record_id):
        myspace = self
        myspace.login_myspace(user, passwd)
        myspace.switch_Asset()
        myspace.enable_bpm_approve()
        transfer_url = myspace.view_approval_common(record_id)
        approve_url = myspace.get_transfer_by_choice_module(transfer_url)
        sess = myspace.session  # session返回给流程平台使用
        return sess, approve_url



if __name__ == "__main__":
    # print(env.get(os.environ["api_test_env"]))
    myspace=MySpace_Asset()
    myspace.login_myspace('jq','1QAZ2wsx')
    myspace.switch_Asset()
    myspace.enable_bpm_approve()
    asset = myspace.get_asset()
    receive_type_id = myspace.get_receive_type_id()
    business_id = myspace.add_asset_receive(receive_type_id,asset['id'],asset['name'])
    # business_id = "3a080dc3-6055-41e1-cb58-4fbff95fa3a4"
    transfer_url = myspace.commit_approval_common(business_id)
    full_url = myspace.get_transfer_by_choice_module(transfer_url,'资产接收-规划信息')
    myspace.create_process(full_url)
    # myspace.initiation_process()

